home *** CD-ROM | disk | FTP | other *** search
- #include <ctype.h>
- #include <string.h>
- #include <stdlib.h>
- #include "internal.h"
- #include "../misc/misc.h"
-
- PUBLIC LANG_STRING::LANG_STRING (char _lang, const char *_str)
- {
- lang = _lang;
- str.setfrom (_str);
- }
-
-
- PUBLIC LANG_STRING *LANG_STRINGS::getitem(int no)
- {
- return (LANG_STRING*)ARRAY::getitem(no);
- }
-
-
- PUBLIC TR_STRING::TR_STRING(const char *_id)
- {
- changed = 0;
- id.setfrom (_id);
- }
-
- /*
- Return the ID of the translation unit
- */
- PUBLIC const char *TR_STRING::getid()
- {
- return id.get();
- }
- /*
- Indicate if this translation unit has been modified (by msgscan).
- This implied that the ID is still in use.
- */
- PUBLIC int TR_STRING::was_changed ()
- {
- return changed;
- }
- PUBLIC void TR_STRING::reset_changed ()
- {
- changed = 0;
- rstmodified();
- }
-
- /*
- Return how many translation are available for this translation unit.
- An obsolete message may have 0 translations.
- */
- PUBLIC int TR_STRING::getnblang()
- {
- return tb.getnb();
- }
-
- /*
- Add a comment line to the TR_STRING definition.
- */
- PUBLIC void TR_STRING::add2comment(const char *_comment)
- {
- comment.append (_comment);
- }
-
- /*
- Add a new translation for this message
- */
- PUBLIC SSTRING *TR_STRING::settranslation (char lang, const char *str)
- {
- changed = 1;
- setmodified();
- LANG_STRING *ta = gettranslation (lang);
- if (ta == NULL){
- ta = new LANG_STRING (lang,str);
- tb.add (ta);
- }else{
- ta->str.setfrom (str);
- }
- return &ta->str;
- }
-
- /*
- Get the message for a given language
- Return NULL if not available.
- */
- PUBLIC LANG_STRING *TR_STRING::gettranslation (char lang)
- {
- LANG_STRING *ret = NULL;
- int n = tb.getnb();
- for (int i=0; i<n; i++){
- LANG_STRING *t = tb.getitem(i);
- if (t->lang == lang){
- ret = t;
- break;
- }
- }
- return ret;
- }
- /*
- Remove one translation.
- */
- PUBLIC void TR_STRING::deltranslation (char lang)
- {
- int n = tb.getnb();
- for (int i=0; i<n; i++){
- LANG_STRING *t = tb.getitem(i);
- if (t->lang == lang){
- tb.remove_del (t);
- break;
- }
- }
- }
- /*
- Get the message for a given language
- Return NULL if not available.
- */
- PUBLIC const char *TR_STRING::getmsg (char lang)
- {
- const char *ret = NULL;
- LANG_STRING *t = gettranslation (lang);
- if (t != NULL) ret = t->str.get();
- return ret;
- }
-
- PUBLIC void TR_STRING::write (FILE *fout)
- {
- if (!comment.is_empty()){
- fputs (comment.get(),fout);
- }
- fprintf (fout,"!%s\n",id.get());
- int n = tb.getnb();
- for (int i=0; i<n; i++){
- LANG_STRING *t = tb.getitem(i);
- fprintf (fout," :%c %s\n",t->lang,t->str.get());
- }
- }
-
-
- /*
- Record the string (file name) where the message was defined.
- */
- PUBLIC void TR_STRING::setorigin(const char *str)
- {
- origin.setfrom (str);
- }
-
- /*
- Return the string (generally a file name) telling where the
- message was defined.
- */
- PUBLIC const char *TR_STRING::getorigin()
- {
- return origin.get();
- }
-
- PUBLIC TR_STRINGS::TR_STRINGS()
- {
- version = 0;
- }
-
- PUBLIC TR_STRING *TR_STRINGS::getitem(int no)
- {
- return (TR_STRING*)ARRAY::getitem(no);
- }
- /*
- Find a translation unit with a given ID
- Return NULL if not found.
- */
- PUBLIC TR_STRING *TR_STRINGS::getitem(const char *id)
- {
- TR_STRING *ret = NULL;
- int n = getnb();
- for (int i=0; i<n; i++){
- TR_STRING *t = getitem(i);
- if (strcmp(t->getid(),id)==0){
- ret = t;
- break;
- }
- }
- return ret;
- }
-
-
- /*
- Read a string dictionary
- Return -1 if there was any errors
- */
- PUBLIC int TR_STRINGS::read (const char *fname)
- {
- FILE *fin = vfopen (fname,"r");
- int err = 0;
- if (fin != NULL){
- char buf[1000];
- /* #Specification: string dictionary / format
- The reference dictionary for the translation
- system is an ASCII file. This file
- contain one record for each string resource.
- Each record spans multiple line with the
- following format.
-
- Note that this is not the file used by
- the running program. A binary file is produced
- for each supported language.
-
- So here it is:
-
- #
- # comments
- # ...
- @version 0
- !id
- :lang string ...
- +...
- :lang string ...
- #
- "lang" is a single letter. "string" follows
- "lang".
- The string may continue over several line. A line
- starting with a '+" is a continuation line. Everything
- after is the string, including white spaces.
-
- Empty lines are ignored.
- */
- TR_STRING *cur = NULL;
- SSTRING *curmsg = NULL;
- int noline = 0;
- SSTRING comment;
- while (fgets(buf,sizeof(buf)-1,fin)!=NULL){
- noline++;
- char *pt = str_skip (buf);
- /* #Specification: dictionary file / comments
- msgscan is trying to preserve empty
- lines and comments between translation units.
- Not much inside translation units
- */
- if (pt[0] == '#' || pt[0] == '\0'){
- comment.append (buf);
- }else{
- strip_end (buf);
- if (pt[0] == '@'){
- // Special commands
- pt = str_skip (pt+1);
- if (strncmp(pt,"version",7)==0
- && isspace(pt[7])){
- pt = str_skip(pt+7);
- version = atoi(pt);
- }else{
- fprintf (stderr,"Invalid line %d: %s\n"
- ,noline,buf);
- err++;
- }
- }else if (pt[0] == '!'){
- cur = new TR_STRING (str_skip(pt+1));
- add (cur);
- cur->add2comment(comment.get());
- comment.setfrom ("");
- }else if (pt[0] == ':'){
- curmsg = cur->settranslation (pt[1]
- ,str_skip(pt+2));
- }else if (pt[0] == '+'){
- curmsg->append (pt+1);
- }else if (buf[0] != '\0'){
- fprintf (stderr,"Invalid line %d: %s\n"
- ,noline,pt);
- err++;
- }
- }
- }
- fclose (fin);
- int n = getnb();
- for (int i=0; i<n; i++){
- TR_STRING *t = getitem(i);
- t->reset_changed();
- }
- rstmodified();
-
- }
- return err ? -1 : 0;
- }
-
- /*
- Write back the ASCII dictionary
- Return -1 if any error.
- */
- PUBLIC int TR_STRINGS::write (const char *fname)
- {
- int ret = -1;
- FILE *fout = vfopen (fname,"w");
- if (fout != NULL){
- fprintf (fout,"@version %d\n",version);
- int n = getnb();
- for (int i=0; i<n; i++){
- TR_STRING *t = getitem(i);
- t->write (fout);
- }
- ret = fclose (fout);
- }
- return ret;
- }
-
- /*
- Write back the ASCII dictionary, modified entry first
- Return -1 if any error.
- */
- PUBLIC int TR_STRINGS::write_mod (const char *fname)
- {
- int ret = -1;
- FILE *fout = vfopen (fname,"w");
- if (fout != NULL){
- fprintf (fout,"@version %d\n",version);
- int n = getnb();
- int i;
- for (i=0; i<n; i++){
- TR_STRING *t = getitem(i);
- if (t->was_modified()) t->write (fout);
- }
- for (i=0; i<n; i++){
- TR_STRING *t = getitem(i);
- if (!t->was_modified()) t->write (fout);
- }
- ret = fclose (fout);
- }
- return ret;
- }
-
- /*
- Write the header file
- */
- PUBLIC int TR_STRINGS::writeh(const char *sysname, const char *fname)
- {
- int ret = -1;
- FILE *fout = vfopen (fname,"w");
- if (fout != NULL){
- fprintf (fout,"extern const char **_dictionary_%s;\n"
- ,sysname);
- fprintf (fout,"#ifndef DICTIONARY_REQUEST\n");
- fprintf (fout,"\t#define DICTIONARY_REQUEST \\\n"
- "\tconst char **_dictionary_%s;\\\n"
- "\tTRANSLATE_SYSTEM_REQ _dictionary_req_%s(\"%s\",_dictionary_%s,%d,%d);\\\n"
- "\tvoid dummy_dict_%s(){}\n"
- ,sysname,sysname,sysname,sysname,getnb(),version,sysname);
- fprintf (fout,"#endif\n");
- fprintf (fout,"#ifndef MSG_U\n");
- fprintf (fout,"\t#define MSG_U(id,m)\tid\n");
- fprintf (fout,"\t#define MSG_B(id,m,n)\tid\n");
- fprintf (fout,"\t#define MSG_R(id)\tid\n");
- fprintf (fout,"#endif\n");
- int n = getnb();
- for (int i=0; i<n; i++){
- TR_STRING *t = getitem(i);
- fprintf (fout,"#define %s\t_dictionary_%s[%d]\n"
- ,t->getid(),sysname,i);
- }
- ret = fclose (fout);
- }
- return ret;
- }
-
- /*
- Record a version number only if it is higher than the current one.
- */
- PUBLIC void TR_STRINGS::setversion (int ver)
- {
- if (ver > version) version = ver;
- }
-
- /*
- Return the version number of this dictionary.
- */
- PUBLIC int TR_STRINGS::getversion ()
- {
- return version;
- }
-
- /*
- Remove one translation for all messages.
- */
- PUBLIC void TR_STRINGS::deltranslation (char lang)
- {
- int n = getnb();
- for (int i=0; i<n; i++){
- TR_STRING *t = getitem(i);
- t->deltranslation (lang);
- }
- }
-
- /*
- Show all obsolete message.
- */
- PUBLIC void TR_STRINGS::showold (char deflang)
- {
- int n = getnb();
- for (int i=0; i<n; i++){
- TR_STRING *t = getitem(i);
- LANG_STRING *l = t->gettranslation (deflang);
- if (l == NULL){
- fprintf (stderr,"Obsolete message: %s\n",t->getid());
- }
- }
- }
-
-
-